﻿using Amazon.S3;
using Microsoft.AspNetCore.Mvc;
using Nasty.Core.Attributes;
using System.Net.Mime;
using Microsoft.AspNetCore.Authorization;
using Nasty.Core.Service;
using System.Drawing.Imaging;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Processing;
using Nasty.Core.SuperExtension;

namespace Nasty.SystemModule.Areas.File.Controllers
{
    [Area("System")]
    [Route("[Area]/[controller]/[action]"), ApiExplorerSettings(GroupName = "System")]
    [ApiController]
    [NastyAuthorize(AuthenticationSchemes = "Bearer,Cookies")]
    public class FileController : ControllerBase
    {
        private readonly IFileService m_FileService;
        private readonly ILogger<FileController> _logger;

        public FileController(ILogger<FileController> logger, IFileService p_FileService)
        {
            _logger = logger;
            m_FileService = p_FileService;
        }

        [HttpPost]
        public async Task<IActionResult> SaveFile(IFormFile file, string? bucket)
        {
            var res = await m_FileService.SaveFile(file, true, bucket);
            if (res.IsSuccess)
            {
                return Ok(res.Data);
            }
            else
            {
                return BadRequest(res.Message);
            }
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> Preview([FromQuery] string key, string? w, string? h, string? bucket)
        {
            if (string.IsNullOrEmpty(key))
            {
                return BadRequest("文件 Key 不能为空");
            }

            (Stream Response, string ContentType) res = (null, string.Empty);

            try
            {
                //保存原始的 key 以便生成 ETag
                var oKey = key;
                var nKey = key;

                var nameExtension = key.NameExtension();

                if (!string.IsNullOrEmpty(w) && !string.IsNullOrEmpty(h)) nKey = $"{nameExtension.Name}-{w}x{h}.{nameExtension.Extension}";

                // 生成 ETag（可以使用文件的哈希值或其他唯一标识符）
                var eTag = $"\"{nKey.GetHashCode()}\"";

                // 检查客户端是否发送了 If-None-Match 头
                if (Request.Headers.TryGetValue("If-None-Match", out var clientETag) && clientETag == eTag)
                {
                    // 如果 ETag 匹配，返回 304 Not Modified
                    return StatusCode(304);
                }


                if (!string.IsNullOrEmpty(w) && !string.IsNullOrEmpty(h))
                {
                    var isExist = m_FileService.IsExist(nKey, bucket);
                    if (isExist)
                    {
                        res = await m_FileService.GetFile(nKey, bucket);
                    }
                    else
                    {
                        res = await m_FileService.GetFile(oKey, bucket);
                        if (int.TryParse(w, out int width) && int.TryParse(h, out int height))
                        {
                            using var memoryStream = new MemoryStream();
                            await res.Response.CopyToAsync(memoryStream);
                            res.Response.Dispose();

                            byte[] imageBytes = memoryStream.ToArray();
                            IImageFormat format = Image.DetectFormat(imageBytes) ?? SixLabors.ImageSharp.Formats.Png.PngFormat.Instance;

                            using var image = SixLabors.ImageSharp.Image.Load(imageBytes);
                            image.Mutate(x => x.Resize(width, height));
                            var ms = new MemoryStream();
                            image.Save(ms, format);
                            ms.Position = 0;

                            var buffer = ms.ToArray();

                            // 存入 S3（异步，不阻塞主流程）
                            _ = Task.Run(async () =>
                            {
                                var uploadFile = buffer.ToFormFile(nKey, res.ContentType);
                                var result = await m_FileService.SaveFile(uploadFile, false, bucket);
                            });

                            // 直接返回本地生成的缩略图流，无需再拉取
                            res = (ms, res.ContentType);
                        }
                    }
                }
                else
                {
                    res = await m_FileService.GetFile(oKey, bucket);
                }


                if (!res.ContentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
                {
                    return BadRequest("仅支持图片格式预览");
                }

                // 设置缓存头
                Response.Headers["Cache-Control"] = "public, max-age=3600"; // 缓存 1 小时
                Response.Headers["ETag"] = eTag;
                Response.Headers["Last-Modified"] = DateTime.UtcNow.ToString("R"); // 设置最后修改时间
                                                                                   // 使用 FileStreamResult 返回图片流
                return new FileStreamResult(res.Response, res.ContentType);
            }
            catch (AmazonS3Exception ex)
            {
                return NotFound("文件不存在或无法访问");
            }
            catch (Exception ex)
            {
                return StatusCode(500, "文件预览失败");
            }
        }

        [HttpGet]
        [AllowAnonymous]
        public async Task<IActionResult> Download([FromQuery] string key, string? bucket)
        {
            if (string.IsNullOrEmpty(key))
            {
                return BadRequest("文件 Key 不能为空");
            }

            try
            {
                // 调用 IFileService 获取文件流和内容类型
                var res = await m_FileService.GetFile(key, bucket);
                // 设置文件下载的 Content-Disposition 响应头
                var contentDisposition = new ContentDisposition
                {
                    FileName = Uri.EscapeDataString(key), // 使用 key 作为文件名，或根据需求自定义
                    Inline = false  // 设置为 false 表示下载而不是直接显示
                };

                Response.Headers["Content-Disposition"] = contentDisposition.ToString();

                // 返回文件流
                return File(res.Response, res.ContentType);
            }
            catch (AmazonS3Exception ex)
            {
                _logger.LogError(ex, "文件下载失败");
                return NotFound("文件不存在或无法访问");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "文件下载失败");
                return StatusCode(500, "文件下载失败");
            }


        }
    }
}
